# -*- coding: utf-8 -*-
"""
Created on Mon Nov 18 11:32:51 2019

@author: HP
"""
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
# 使用echart画可交互图：
from pyecharts import options as opts
from pyecharts.charts import Graph, Page
from pyecharts.globals import ThemeType


# 将好友推荐的结果进行可视化！
def brec_viz(graph,new_user,candidates,seeds,title,plot_ego_graph=True):
    graph = graph
    center = new_user
    friends = list(graph.neighbors(center))
    if plot_ego_graph:
        arounds = []
        for n in list(graph.neighbors(center)):
            arounds.append(n)
            arounds += graph.neighbors(n)
        arounds = list(set(arounds))
        graph = graph.subgraph(arounds)
        candidates = [n for n in candidates if n in arounds]
        seeds = [s for s in seeds if s in arounds]
    
    cross_users = list(set(friends).intersection(set(candidates)))
    plt.figure(figsize=(8,5))
    pos = nx.spring_layout(graph,seed=1)
    options = {'node_color': 'black',\
           'node_size': 0.5,\
           'edge_color':'gray',\
           'width': 0.2}
    # 画全图：
    nx.draw(graph, pos, **options)
    # 画中心点：
    nx.draw_networkx_nodes(graph, pos, nodelist=[center], node_size=100, node_color='black', label='New User')
    # 画seeds：
    nx.draw_networkx_nodes(graph, pos, nodelist=seeds, node_size=150,node_color='g',alpha=0.4, label='Seeds(%d)'%len(seeds))
    # 画朋友节点：
    nx.draw_networkx_nodes(graph, pos, nodelist=friends, node_size=30,node_color='r', label='Goals(%d)'%len(friends))
    # 画拓展节点：
    nx.draw_networkx_nodes(graph, pos, nodelist=candidates, node_size=30, node_color='b', label='Shoots(%d)'%len(candidates))
    # 画交叉节点：
    nx.draw_networkx_nodes(graph, pos, nodelist=cross_users, node_size=30, node_color='purple', label='Hits(%d)'%len(cross_users))
    fontdict={'family': 'Arial', 'color': 'black', 'weight': 'normal', 'size': 20}
    plt.title("Friends Recommendation for User %s using %s"%(center,title),fontdict=fontdict)
    plt.legend()
    for i,n in enumerate(candidates):
        plt.annotate(str(i+1),xy=(pos[n][0],pos[n][1]),xytext=(pos[n][0],pos[n][1]))
    plt.show()


def brec_viz_iteractive(graph,new_user,candidates,seeds,method,plot_ego_graph,params_text) -> Graph:
    print(params_text)
    title = 'Friends Rec for user 【%s】 with 【%s】'%(new_user,method)
    center = new_user
    friends = list(graph.neighbors(center))
    repulsion = 7
    width='1500px'
    height='900px'
    shrink = 1
    if plot_ego_graph:
        title = title+' in 2-hop network.'
        repulsion = 80
        width='900px'
        height='500px'
        shrink = 0.5
        arounds = []
        for n in list(graph.neighbors(center)):
            arounds.append(n)
            arounds += graph.neighbors(n)
        arounds = list(set(arounds))
        graph = graph.subgraph(arounds)
        candidates = [n for n in candidates if n in arounds]
        seeds = [s for s in seeds if s in arounds]  
    cross_users = list(set(friends).intersection(set(candidates)))
    
    exist_nodes = [new_user]
    all_nodes = []
    
    center_node = {"name": str(new_user), "symbolSize": 35*shrink,"category":0}
    all_nodes.append(center_node)
    

    for cross_user in cross_users:
        if cross_user not in exist_nodes:
            all_nodes.append({"name": str(cross_user), "symbolSize": 30*shrink,"category":4})
            exist_nodes.append(cross_user)
            
    for seed in seeds:
        if seed not in exist_nodes:
            all_nodes.append({"name": str(seed), "symbolSize": 30*shrink,"category":1})
            exist_nodes.append(seed)
            
    for friend in friends:
        if friend not in exist_nodes:
            all_nodes.append({"name": str(friend), "symbolSize": 30*shrink,"category":2})
            exist_nodes.append(friend)
            
    for candidate in candidates:
        if candidate not in exist_nodes:
            all_nodes.append({"name": str(candidate), "symbolSize": 15*shrink,"category":3})
            exist_nodes.append(candidate)
            
    for user in list(graph.nodes):
        if user not in exist_nodes:
            all_nodes.append({"name": str(user), "symbolSize": 3*shrink,"category":0})
            exist_nodes.append(user)
            
    assert len(exist_nodes) == len(graph.nodes), "节点总数不对"
    
    links = []
    for edge in list(graph.edges):
        links.append({"source": str(edge[0]), "target": str(edge[1])})
    
    categories = [
            {"name":"Users","symbol":'circle'},
            {"name":"Seeds(%s)"%len(seeds),"symbol":'circle'},
            {"name":"Friends(%s)"%len(friends),"symbol":'circle'},
            {"name":"Candidates(%s)"%len(candidates),"symbol":'circle'},
            {"name":"Hits(%s)"%len(cross_users),"symbol":'circle'}
    ]
    c = (
        Graph(init_opts = opts.InitOpts(width=width,height=height,\
                                        page_title = title,theme=ThemeType.SHINE))
        .add("", all_nodes, links, categories, repulsion=repulsion,\
             label_opts={"is_show":False},linestyle_opts={"width":0.5})
        .set_global_opts(title_opts=opts.TitleOpts(title=title,subtitle=params_text,pos_right='center',pos_top='top'),\
                         legend_opts=opts.LegendOpts(pos_right='right',pos_top='center',orient='vertical'))
    )
    c.render('../images/%s.html'%title)
    print('Saved at','../images/%s.html'%title)



# 用户对特征生成：
def musae_feature_fusion(u1,u2,feature_dict):
    f1 = feature_dict[str(u1)]
    f2 = feature_dict[str(u2)]
    ABS = np.abs(f1-f2)
    MUL = np.multiply(f1,f2)
    return np.concatenate([f1,f2,ABS,MUL])










